package tools;

import java.util.Iterator;

import util.Memorier;


public abstract class Vector<T> implements Comparable<Vector<T> >{
	
	protected T[] list;
	protected Memorier mem;
	protected int dim;
	
	protected  abstract T define0();

	public Vector(int dim){
		mem = new Memorier();
		mem.addLongSize();
		this.dim = dim;
	}
	
	public abstract Vector<T> copy();

	public int getDim(){
		return dim;
	}
	
	public void set(int j, T elem){
		list[j] = elem;
	}
	
	public T get(int i){
		return list[i];
	}

	public boolean isEqual(int i, Vector<T> other){
		boolean ret = true;
		for(int j = 0; j < i; j++){
			if(list[j] != other.list[j])ret = false;
		}
		return ret;
	}
	
	public abstract boolean isBigger(Vector<T> other, int i);
	
	public abstract boolean isSmaller(Vector<T> other, int i);
	
	public abstract  T sum(int i);
	
	public abstract T sum(int i, int j);
	
	public double memoryUsedB(){
		return mem.getUsedMemB();
	}
	
	public double memoryUsedKB(){
		return mem.getUsedMemKB();
	}
	
	public double memoryUsedMB(){
		return mem.getUsedMemMB();
	}
	
	public Iterator<T> iterator(){
		return new Iterator<T>(){
			private int index = 0;
			private int lim = dim;

			public boolean hasNext() {return index < lim; }

			public T next() {return list[index]; }

			public void remove() {
				index++;
			}
			
		};
	}

	public Vector<T> getProjection(int k) {
		Vector<T> cp = copy();
		
		for(int i = k >= 0? k+1:0; i < dim; i++){
			cp.set(i, define0());
		}
		return cp;
	}
	
	public int compareTo(Vector<T> o) {
		if(equals(o)) return 0;
		if(isBigger(o, dim)) return 1;
		return -1;
	}
	
	public boolean equals(Object o){
		for(int i = 0; i < dim; i++) if(!list[i].equals(((Vector<T>)o).list[i])) return false;
		return true;
	}
	
	public void print(){
		for(int i = 0; i < dim; i++){
			System.out.print(get(i) + "\t");
		}
		System.out.println("");
	}
	
	public String toString(){
		String ret = new String();
		ret += Integer.toString(dim) + "\n";
		for(int i = 0; i < dim; i++){
			ret += get(i).toString() + "\n";
		}
		return ret;
	}
	
	public void finalize(){
		list = null;
	}
}
